#include "mkl_vsl.h"
#include <map>
#include <climits>

using namespace std;

class RandomGenerator;
typedef map<const int, RandomGenerator*> generatorMap; 
generatorMap generators;


class RandomGenerator{

public:
	RandomGenerator(const MKL_INT type, const unsigned MKL_INT seed){
		vslNewStream( &stream, type, seed );
	}
	
	~RandomGenerator(){
		vslDeleteStream( &stream );
	}

	int generateRandomNumbers(const MKL_INT n, double values[]){
		return vdRngUniform( VSL_METHOD_DUNIFORM_STD_ACCURATE, stream, n, values, 0.0, 1.0 );	
	}

private:
	VSLStreamStatePtr stream;

};

unsigned int count = 1;

extern "C"{

	unsigned int create_generator(const MKL_INT type, const unsigned MKL_INT seed){
		unsigned id = count++;
		unsigned int i = 0;
		bool added = false;
		while( i < INT_MAX)	{
			if( generators.find(id) == generators.end() ) {
				generators[id] = new RandomGenerator(type, seed);
				added = true;
				break;
			}
			id = count++;
			if( id == 0 ){
				id = count++;
			}
			i++;
		}
		return added ? id : 0;
	}

	int call_generator(const unsigned int id, const MKL_INT n, double values[]){
		generatorMap::iterator it = generators.find(id);
		if( it == generators.end() ){
			return VSL_ERROR_NULL_PTR;
		}
		
		return it->second->generateRandomNumbers(n, values);
	}

	void delete_generator(const unsigned int id){
		generatorMap::iterator it = generators.find(id);
		if( it != generators.end() ){
			delete it->second;
			generators.erase(it);
		}
	}
}